// 一
// 1
// 不是响应式数据
// Vue中的data数据的响应式是通过初始化时的new Observer()，新添加的成员没有经过new Observer()处理，只是Vue实例上的一个属性。
// 修改
// data{
//     dog:{
//         name:''
//     }
// }

// 2
// diff算法的执行过程:(拿snabbdom举例)就是一个patch函数，通过接收参数传过来的oldDom和newDom也就是新旧节点，先去比较节点本身
// 如果一样再比较子节点，如果不一样，就把老节点替换成新节点，(如果只是text(文本)不一样，就只更新文本)，如果一样就重用之前的节点。

// 二
// 1
let _Vue = null
export default class VueRouter{
    static install(Vue){
        if(VueRouter.install.installed){
            return
        }
        VueRouter.install.installed = true
        _Vue = Vue
        _Vue.mixin({
            beforeCreate(){
                if(this.$options.router){
                    _Vue.prototype.router = this.$options.router
                    this.$options.router.init()
                }
            }
        })
    }
    constructor(options) {
        this.options = options
        this.routeMap = {}
        this.data = _Vue.observable({
            current: '/'
        })
    }
    init() {
        this.createRouteMap()
        this.initComponents(_Vue)
        this.initEvent()
    }
    createRouteMap(){
        this.options.routes.forEach((route)=>{
            this.routeMap[route.path] = route.component
        })
    }
    initComponents(vue){
        vue.component('router-link', {
            props:{
                to: String
            },
            render(h){
                h(
                    'a',
                    {
                        attrs:{
                            href: this.to
                        },
                        on:{
                            click: this.clickHandle
                        }
                    }
                    ,[this.$slots.default]
                )
            },
            method:{
                clickHandle(e){
                    history.pushState({}, '',this.to)
                    this.$router.data.current = this.to
                    e.preventDefault()
                }
            }
        })

        const selt = this
        vue.component('router-view',{
            render(h) {
                const component = selt.routeMap[selt.data.current]
                return h(component)
            }
        })
    }
    initEvent(){
        window.addEventListener('popstate', () => {
            this.data.current = window.location.pathname
        })
    }

}

// 2
export default class VHtml{
    textUpdater(node, value, key){
        node.textContent = value
        new Watcher(this.vm, key, (newValue) => {
            node.textContent = newValue
        })
    }
}

export default class VOn{
    compileElement(node){
        Array.from(node.attributes).forEach((attr)=>{
            console.log(attr);
            let attrName = attr.name
            if(this.isDirective(attrName)){
                attrName = attrName.substr(2)
                let key = attr.value
                this.update(node, key, attrName)
            }
        })
    }
    update(node, key, attrName){
        let updateFn =  this[attrName + 'Updater']
        updateFn && updateFn.call(this, node, this.vm[key], key)
    }
}
